The stable marriage problem is the problem of finding a stable matching between two equally sized sets of elements given an ordering of preferences for each element. A matching is a mapping from the elements of one set to the elements of the other set.
A matching is not stable if:
In other words, a matching is stable when there does not exist any match (A, B) by which both A and B would be individually better off than they are with the element to which they are currently matched.
In [1]:
    
from collections import deque, defaultdict
    
In [17]:
    
def gale_shapley(men, women):
    free_men = deque(men)
    marriages = defaultdict(lambda: None)
    
    preferences = dict()
    for jane in women:
        for i, john in enumerate(women[jane]):
            preferences[(jane, john)] = i
    
    while free_men:
        john = free_men.popleft()
        
        for jane in men[john]:
            fiance = marriages[jane]
            
            if fiance is None or preferences[(jane, john)] < preferences[(jane, fiance)]:
                marriages[jane] = john
                
                if fiance is not None:
                    free_men.append(fiance)
                break
                    
    return list(sorted((m, w) for w, m in marriages.items()))
    
In [18]:
    
men = {
    'adam': ['claire', 'diana'],
    'bob': ['diana', 'claire']
}
women = {
    'claire': ['bob', 'adam'],
    'diana': ['adam', 'bob']
}
gale_shapley(men, women)
    
    Out[18]:
In [19]:
    
men = {
    1: [2, 4, 1, 3],
    2: [3, 1, 4, 2],
    3: [2, 3, 1, 4],
    4: [4, 1, 3, 2]
}
women = {
    1: [2, 1, 4, 3],
    2: [4, 3, 1, 2],
    3: [1, 4, 3, 2],
    4: [2, 1, 4, 3]
}
gale_shapley(men, women)
    
    Out[19]:
In [20]:
    
men = {
    'adam': ['betty', 'claire', 'diana'],
    'bob': ['betty', 'claire', 'diana'],
    'charlie': ['betty', 'claire', 'diana']
}
women = {
    'betty': ['charlie', 'bob', 'adam'],
    'claire': ['charlie', 'bob', 'adam'],
    'diana': ['charlie', 'bob', 'adam']
}
gale_shapley(men, women)
    
    Out[20]:
In [21]:
    
men = {
    'alex': ['alice', 'beatrice', 'christina'],
    'ben': ['beatrice', 'alice', 'christina'],
    'charlie': ['beatrice', 'christina', 'alice']
}
women = {
    'alice': ['alex', 'charlie', 'ben'],
    'beatrice': ['charlie', 'alex', 'ben'],
    'charlie': ['alex', 'charlie', 'ben']
}
gale_shapley(men, women)
    
    Out[21]: